home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************************\
- *
- * Copyright (C) 1994, Carnegie Mellon University
- * All rights reserved.
- *
- * This code was produced by the Gwydion Project at Carnegie Mellon
- * University. If you are interested in using this code, contact
- * "Scott.Fahlman@cs.cmu.edu" (Internet).
- *
- ***********************************************************************
- *
- * $Header: extern.c,v 1.2 94/11/30 16:17:18 rgs Exp $
- *
- * This file provides support for manipulating native C pointers.
- *
- \**********************************************************************/
-
- #include "../compat/std-c.h"
-
- #include "mindy.h"
- #include "gc.h"
- #include "obj.h"
- #include "bool.h"
- #include "char.h"
- #include "list.h"
- #include "type.h"
- #include "class.h"
- #include "def.h"
- #include "sym.h"
- #include "module.h"
- #include "error.h"
- #include "thread.h"
- #include "func.h"
- #include "extern.h"
- #include "num.h"
- #include "str.h"
- #include "print.h"
- #include "coll.h"
- #ifdef hp9000s800
- #include <sys/file.h>
- /*
- #include <stdio.h>
- #include <stdlib.h>
- */
- #include <a.out.h>
- #include <aouthdr.h>
- #include <filehdr.h>
- #include <syms.h>
- #include <sys/mman.h>
- #include <unistd.h>
- #endif
-
- obj_t obj_CPointerClass = NULL; /* all instances of StaticTypeClass are
- subclasses of this one */
- obj_t obj_ForeignFileClass = NULL;
- obj_t obj_NullPointer = NULL;
- obj_t /* <foreign-file> */ mindy_explicit_syms = NULL;
-
- static obj_t /* <foreign-file> */ mindy_dynamic_syms = NULL;
-
- obj_t make_c_pointer(obj_t /* <static-pointer-class> */ cls, void *ptr)
- {
- obj_t res = alloc(cls, sizeof(struct c_pointer));
-
- C_PTR(res)->pointer = ptr;
-
- return res;
- }
-
- /* Dylan routines. */
-
- /* Reads the symtab (in some machine specific format) from the named file
- and returns a "foreign_file" object which allows access to those symbols */
- obj_t load_c_symtab(obj_t /* <string> */ abs_file)
- {
- int fd, count, total = 0;
- char *file = string_chars(abs_file);
- obj_t res;
-
- #if defined(hp9000s800)
- struct header hdr;
- struct symtab *retval;
- int sym_count, sym_size, sym_loc, string_size, string_loc, table_size;
- struct symbol_dictionary_record *syms;
- char *strings;
- int i, j;
-
- /* Read beginning of "file" into "hdr" */
- fd = open(file, O_RDONLY, 0);
- if (fd < 0) return 0;
- for (count = read(fd, ((char *)&hdr), sizeof(hdr)), total = count;
- count > 0 && total < sizeof(hdr);
- count = read(fd, ((char *)&hdr + total), sizeof(hdr) - total),
- total += count) ;
- if (total < sizeof(hdr)) return 0;
-
- /* Read in symbol table */
- sym_count = hdr.symbol_total;
- sym_loc = hdr.symbol_location;
- sym_size = sizeof(struct symbol_dictionary_record) * sym_count;
- if ((syms = (struct symbol_dictionary_record *) malloc(sym_size)) == NULL)
- return 0;
- if (lseek(fd, sym_loc, 0) < 0) return 0;
- for (count = read(fd, (char *) syms, sym_size), total = count;
- count > 0 && total < sym_size;
- count = read(fd, ((char *) syms) + total, sym_size - total),
- total += count) ;
- if (total < sym_size) return 0;
-
- string_size = hdr.symbol_strings_size;
- table_size = (sym_count - 1) * sizeof(struct symtab);
- res = alloc(obj_ForeignFileClass,
- sizeof(struct foreign_file) + table_size + string_size);
- FOREIGN_FILE(res)->extra_size = string_size + table_size;
-
- retval = FOREIGN_FILE(res)->syms;
- strings = (char *)retval + table_size;
-
- /* Read in symbol table strings */
- string_loc = hdr.symbol_strings_location;
- if (lseek(fd, string_loc, 0) < 0) return 0;
- for (count = read(fd, strings, string_size), total = count;
- count > 0 && total < string_size;
- count = read(fd, strings + total, string_size - total),
- total += count) ;
- if (total < string_size) return 0;
-
- close(fd);
-
- if (retval == NULL) return 0;
- for (i = 0, j = 0; i < sym_count; i++)
- if (syms[i].symbol_scope == SS_UNIVERSAL) {
- retval[j].name = strings + syms[i].name.n_strx;
- switch (syms[i].symbol_type) {
- case ST_DATA:
- retval[j++].ptr = (void *) syms[i].symbol_value;
- break;
- case ST_CODE:
- case ST_PRI_PROG:
- case ST_SEC_PROG:
- case ST_ENTRY:
- case ST_MILLICODE:
- retval[j++].ptr = (void *) (syms[i].symbol_value & 0xfffffffc);
- break;
- default:
- retval[j++].ptr = 0;
- }
- }
-
- FOREIGN_FILE(res)->file_name = abs_file;
- FOREIGN_FILE(res)->sym_count = j;
-
- return res;
- #else
- return obj_False;
- #endif
- }
-
- /* Links the named object files for dynamic loading, reads it in, and returns
- a "foreign_file" object which allows access to its symbols. If
- names is a non-empty list (of byte-strings), then make ld "undefine"
- these names so that they will show up in the linked version. */
- obj_t load_c_file(obj_t /* list */ c_files, obj_t /* list */ names)
- /* c_file is a <string> */
- {
- #ifdef hp9000s800
- char *execstr;
- int execlimit = 1024, execsize;
- char *absfile;
- obj_t res, file_name = obj_False;
- static int pagesize = 0;
- int fd, count, total, codesize, bss_size, mapresult;
- struct header hdr;
- struct som_exec_auxhdr aux;
- static void *addr = (void *)0x20000000;
-
- if (pagesize == 0) pagesize = sysconf(_SC_PAGE_SIZE);
-
- execstr = malloc(execlimit);
- absfile = tmpnam(NULL);
- sprintf(execstr, "/bin/ld -N -o %s -E -A %s -R %x",
- absfile, exec_file_name, (int) addr);
- execsize = strlen(execstr);
- /* append each object file */
- for ( ; c_files != obj_Nil; c_files = TAIL(c_files)) {
- int flaglen = obj_ptr(struct string *, HEAD(c_files))->len + 1;
- if ((execsize + flaglen + 1) > execlimit) {
- execlimit += 1024;
- execstr = realloc(execstr, execlimit);
- }
- if (file_name == obj_False) file_name = HEAD(c_files);
- sprintf(execstr+execsize, " %s", string_chars(HEAD(c_files)));
- execsize += flaglen;
- }
- /* undefine each of the names we were given */
- for ( ; names != obj_Nil; names = TAIL(names)) {
- int flaglen = obj_ptr(struct string *, HEAD(names))->len + 4;
- if ((execsize + flaglen + 1) > execlimit) {
- execlimit += 1024;
- execstr = realloc(execstr, execlimit);
- }
- sprintf(execstr+execsize, " -u %s", string_chars(HEAD(names)));
- execsize += flaglen;
- }
- if (system(execstr) != 0)
- return NULL; /* unknown failure */
-
- /* Read beginning of "file" into "hdr" */
- fd = open(absfile, O_RDONLY, 0);
- if (fd < 0) return 0;
- for (count = read(fd, ((char *)&hdr), sizeof(hdr)), total = count;
- count > 0 && total < sizeof(hdr);
- count = read(fd, ((char *)&hdr + total), sizeof(hdr) - total),
- total += count) ;
- if (total < sizeof(hdr)) return NULL;
-
- if (lseek(fd, hdr.aux_header_location, 0) < 0) return NULL;
- for (count = read(fd, ((char *)&aux), sizeof(aux)), total = count;
- count > 0 && total < sizeof(aux);
- count = read(fd, ((char *)&aux + total), sizeof(aux) - total),
- total += count) ;
- if (total < sizeof(aux)) return NULL;
-
- codesize = ((aux.exec_tsize + pagesize - 1) / pagesize) * pagesize;
- mapresult =
- (int) mmap((void *) aux.exec_tmem, codesize,
- PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_FIXED | MAP_PRIVATE | MAP_FILE, fd, aux.exec_tfile);
- if (mapresult < 0)
- return NULL;
- if (aux.exec_tmem + codesize > (int)addr)
- addr = (void *)(aux.exec_tmem + codesize);
-
- codesize = ((aux.exec_dsize + pagesize - 1) / pagesize) * pagesize;
- if (mmap((void *)aux.exec_dmem, codesize,
- PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_FIXED | MAP_PRIVATE | MAP_FILE, fd, aux.exec_dfile) < 0)
- return NULL;
-
- bss_size = ((aux.exec_bsize + pagesize - 1) / pagesize) * pagesize;
- if (mmap((void *)(aux.exec_dmem + codesize), bss_size,
- PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) < 0)
- return NULL;
- if (aux.exec_bfill != 0)
- error("Non-zero BSS fill value -- must fix extern.c");
- if (aux.exec_dmem + codesize + bss_size > (int)addr)
- addr = (void *)(aux.exec_dmem + codesize + bss_size);
-
- close(fd);
-
- res = load_c_symtab(make_byte_string(absfile));
- FOREIGN_FILE(res)->file_name = file_name;
- unlink(absfile);
-
- return res;
- #else
- error("Dynamic loading is not supported for this architecture.");
- return obj_False;
- #endif
- }
-
- static void print_foreign_file(obj_t file)
- {
- printf("{<foreign-file> %s}", string_chars(FOREIGN_FILE(file)->file_name));
- }
-
- static void print_c_pointer(obj_t ptr)
- {
- obj_t class = C_PTR(ptr)->class;
- obj_t class_name = obj_ptr(struct class *, class)->debug_name;
- char *class_str;
-
- if (class_name != NULL && class_name != obj_False)
- class_str = sym_name(class_name);
- else
- class_str = "<c-pointer>";
-
- printf("{%s 0x%08lx}", class_str, (unsigned long)(C_PTR(ptr)->pointer));
- }
-
- /* Look for an object with the given name in the named file and return a
- callable "<c-function>" object for it. */
- obj_t find_c_function(obj_t /* <string> */ symbol, obj_t lookup)
- {
- char *string = string_chars(symbol);
- struct symtab *syms;
- int sym_count, i;
- obj_t retval = obj_False;
-
- if (lookup == obj_Unbound) {
- retval = find_c_function(symbol, mindy_explicit_syms);
- if (retval != obj_False) return retval;
-
- if (mindy_dynamic_syms == NULL)
- mindy_dynamic_syms = load_c_symtab(make_byte_string(exec_file_name));
- return find_c_function(symbol, mindy_dynamic_syms);
- } else if (lookup == obj_False)
- return obj_False;
- else if (object_class(lookup) != obj_ForeignFileClass) {
- error("Keyword file: is not a <foreign-file>: %=", lookup);
- return retval; /* make lint happy */
- } else {
- syms = FOREIGN_FILE(lookup)->syms;
- sym_count = FOREIGN_FILE(lookup)->sym_count;
- for (i = 0; i < sym_count; i++)
- if (strcmp(syms[i].name, string) == 0) {
- retval = make_c_function(make_byte_string(string),
- syms[i].ptr);
- break;
- }
- return retval;
- }
- }
-
- /* Look for an object with the given name in the named file and return a
- "<c-pointer>" object for it. */
- obj_t find_c_ptr(obj_t /* <string> */ symbol, obj_t lookup)
- {
- char *string = string_chars(symbol);
- struct symtab *syms;
- int sym_count, i;
- obj_t retval = obj_False;
-
- if (lookup == obj_Unbound) {
- retval = find_c_ptr(symbol, mindy_explicit_syms);
- if (retval != obj_False) return retval;
-
- if (mindy_dynamic_syms == NULL)
- mindy_dynamic_syms = load_c_symtab(make_byte_string(exec_file_name));
- return find_c_ptr(symbol, mindy_dynamic_syms);
- } else if (lookup == obj_False)
- return obj_False;
- else if (object_class(lookup) != obj_ForeignFileClass) {
- error("Keyword file: is not a <foreign-file>: %=", lookup);
- return retval; /* make lint happy */
- } else {
- syms = FOREIGN_FILE(lookup)->syms;
- sym_count = FOREIGN_FILE(lookup)->sym_count;
- for (i = 0; i < sym_count; i++)
- if (strcmp(syms[i].name, string) == 0) {
- retval = make_c_pointer(obj_CPointerClass, syms[i].ptr);
- break;
- }
- return retval;
- }
- }
-
- /* Tries to return a version of some Dylan object which will be
- meaningful to C. This may include a pointer, an integer, or
- something else. We assume that it can be freely cast to and from a
- pointer. */
- void *get_c_object(obj_t obj)
- {
- obj_t cls = object_class(obj);
-
- if (object_class(cls) == obj_StaticTypeClass)
- return C_PTR(obj)->pointer;
- else if (cls == obj_IntegerClass || cls == obj_FixnumClass)
- return (void *)fixnum_value(obj);
- else if (cls == obj_ByteStringClass)
- return (void *)string_chars(obj);
- else if (cls == obj_CharacterClass)
- return (void *)(int)char_int(obj);
- else if (cls == obj_BooleanClass)
- return (void *)(obj != obj_False);
- else
- return NULL;
- }
-
- /* Tries to convert a C return value back into a dylan object. */
- obj_t convert_c_object(obj_t cls, void *obj, boolean miss_ok)
- {
- if (cls == obj_ObjectClass)
- return make_c_pointer(obj_CPointerClass, obj);
- else if (object_class(cls) == obj_StaticTypeClass)
- return make_c_pointer(cls, obj);
- else if (cls == obj_CFunctionClass)
- return make_c_function(make_byte_string("(unknown)"), obj);
- else if (cls == obj_IntegerClass || cls == obj_FixnumClass)
- return make_fixnum((int) obj);
- else if (cls == obj_ByteStringClass || cls == obj_StringClass)
- return make_byte_string((char *)obj);
- else if (cls == obj_CharacterClass)
- return int_char((int)obj);
- else if (cls == obj_BooleanClass)
- return obj == NULL ? obj_False : obj_True;
- else if (miss_ok)
- return make_c_pointer(obj_CPointerClass, obj);
- else {
- error("Could not coerce c_pointer to class %=", cls);
- return obj_NullPointer;
- }
- }
-
- obj_t signed_byte_at(obj_t /* <statically-typed-pointer> */ pointer,
- obj_t /* <integer> */ offset)
- {
- void *ptr = C_PTR(pointer)->pointer;
- int true_offset = fixnum_value(offset);
-
- if (!obj_is_fixnum(offset))
- error("Offset is not fixnum: %=", offset);
- return make_fixnum(*((char *)((int)ptr + true_offset)));
- }
-
- obj_t signed_byte_at_setter(obj_t /* <integer> */ value,
- obj_t /* <statically-typed-pointer> */ pointer,
- obj_t /* <integer> */ offset)
- {
- void *ptr = C_PTR(pointer)->pointer;
- int true_offset = fixnum_value(offset);
-
- if (!obj_is_fixnum(offset))
- error("Offset is not fixnum: %=", offset);
- *((char *)((int)ptr + true_offset)) = fixnum_value(value);
- return value;
- }
-
- obj_t unsigned_byte_at(obj_t /* <statically-typed-pointer> */ pointer,
- obj_t /* <integer> */ offset)
- {
- void *ptr = C_PTR(pointer)->pointer;
- int true_offset = fixnum_value(offset);
-
- if (!obj_is_fixnum(offset))
- error("Offset is not fixnum: %=", offset);
- return make_fixnum(*((unsigned char *)((int)ptr + true_offset)));
- }
-
- obj_t unsigned_byte_at_setter(obj_t /* <integer> */ value,
- obj_t /* <statically-typed-pointer> */ pointer,
- obj_t /* <integer> */ offset)
- {
- void *ptr = C_PTR(pointer)->pointer;
- int true_offset = fixnum_value(offset);
-
- if (!obj_is_fixnum(offset))
- error("Offset is not fixnum: %=", offset);
- *((unsigned char *)((int)ptr + true_offset)) = fixnum_value(value);
- return value;
- }
-
- obj_t signed_short_at(obj_t /* <statically-typed-pointer> */ pointer,
- obj_t /* <integer> */ offset)
- {
- void *ptr = C_PTR(pointer)->pointer;
- int true_offset = fixnum_value(offset);
-
- if (!obj_is_fixnum(offset))
- error("Offset is not fixnum: %=", offset);
- return make_fixnum(*((short *)((int)ptr + true_offset)));
- }
-
- obj_t signed_short_at_setter(obj_t /* <integer> */ value,
- obj_t /* <statically-typed-pointer> */ pointer,
- obj_t /* <integer> */ offset)
- {
- void *ptr = C_PTR(pointer)->pointer;
- int true_offset = fixnum_value(offset);
-
- if (!obj_is_fixnum(offset))
- error("Offset is not fixnum: %=", offset);
- *((short *)((int)ptr + true_offset)) = fixnum_value(value);
- return value;
- }
-
- obj_t unsigned_short_at(obj_t /* <statically-typed-pointer> */ pointer,
- obj_t /* <integer> */ offset)
- {
- void *ptr = C_PTR(pointer)->pointer;
- int true_offset = fixnum_value(offset);
-
- if (!obj_is_fixnum(offset))
- error("Offset is not fixnum: %=", offset);
- return make_fixnum(*((unsigned short *)((int)ptr + true_offset)));
- }
-
- obj_t unsigned_short_at_setter(obj_t /* <integer> */ value,
- obj_t /* <statically-typed-pointer> */ pointer,
- obj_t /* <integer> */ offset)
- {
- void *ptr = C_PTR(pointer)->pointer;
- int true_offset = fixnum_value(offset);
-
- if (!obj_is_fixnum(offset))
- error("Offset is not fixnum: %=", offset);
- *((unsigned short *)((int)ptr + true_offset)) = fixnum_value(value);
- return value;
- }
-
- obj_t signed_long_at(obj_t /* <statically-typed-pointer> */ pointer,
- obj_t /* <integer> */ offset)
- {
- void *ptr = C_PTR(pointer)->pointer;
- int true_offset = fixnum_value(offset);
-
- if (!obj_is_fixnum(offset))
- error("Offset is not fixnum: %=", offset);
- return make_fixnum(*((long *)((int)ptr + true_offset)));
- }
-
- obj_t signed_long_at_setter(obj_t /* <integer> */ value,
- obj_t /* <statically-typed-pointer> */ pointer,
- obj_t /* <integer> */ offset)
- {
- void *ptr = C_PTR(pointer)->pointer;
- int true_offset = fixnum_value(offset);
-
- if (!obj_is_fixnum(offset))
- error("Offset is not fixnum: %=", offset);
- *((long *)((int)ptr + true_offset)) = fixnum_value(value);
- return value;
- }
-
- obj_t unsigned_long_at(obj_t /* <statically-typed-pointer> */ pointer,
- obj_t /* <integer> */ offset)
- {
- void *ptr = C_PTR(pointer)->pointer;
- int true_offset = fixnum_value(offset);
-
- if (!obj_is_fixnum(offset))
- error("Offset is not fixnum: %=", offset);
- return make_fixnum(*((unsigned long *)((int)ptr + true_offset)));
- }
-
- obj_t unsigned_long_at_setter(obj_t /* <integer> */ value,
- obj_t /* <statically-typed-pointer> */ pointer,
- obj_t /* <integer> */ offset)
- {
- void *ptr = C_PTR(pointer)->pointer;
- int true_offset = fixnum_value(offset);
-
- if (!obj_is_fixnum(offset))
- error("Offset is not fixnum: %=", offset);
- *((unsigned long *)((int)ptr + true_offset)) = fixnum_value(value);
- return value;
- }
-
- obj_t pointer_at(obj_t /* <statically-typed-pointer> */ pointer,
- obj_t /* <integer> */ offset,
- obj_t /* <class> */ cls)
- {
- void *ptr = C_PTR(pointer)->pointer;
- int true_offset = fixnum_value(offset);
-
- if (!obj_is_fixnum(offset))
- error("Offset is not fixnum: %=", offset);
- if (!instancep(cls, obj_StaticTypeClass))
- error("class is not statically typed pointer: %=", cls);
- /* pointer size object -- dereference as (void **) */
- return convert_c_object(cls, *(void **)((char *)ptr + true_offset),
- FALSE);
- }
-
- obj_t pointer_at_setter(obj_t /* <statically-typed-pointer> */ value,
- obj_t /* <statically-typed-pointer> */ pointer,
- obj_t /* <integer> */ offset)
- {
- void *ptr = C_PTR(pointer)->pointer;
- int true_offset = fixnum_value(offset);
-
- if (!obj_is_fixnum(offset))
- error("Offset is not fixnum: %=", offset);
- /* pointer size object -- dereference as (void **) */
- *((void **)((char *)ptr + true_offset)) = get_c_object(value);
- return value;
- }
-
- obj_t pointer_add(obj_t /* <statically-typed-pointer> */ pointer,
- obj_t /* <integer> */ num)
- {
- void *ptr = C_PTR(pointer)->pointer;
- int true_offset = fixnum_value(num);
-
- return make_c_pointer(object_class(pointer),
- (void *)((int)ptr + true_offset));
- }
-
- obj_t pointer_subtract(obj_t /* <statically-typed-pointer> */ pointer1,
- obj_t /* <statically-typed-pointer> */ pointer2)
- {
- void *ptr1 = C_PTR(pointer1)->pointer;
- void *ptr2 = C_PTR(pointer2)->pointer;
-
- return make_fixnum((long int)ptr1 - (long int)ptr2);
- }
-
-
- /* Dereferences a "slot" in the "structure" pointed to by a <c-pointer>. */
- obj_t c_pointer_field(obj_t pointer, obj_t offset, obj_t cls, obj_t deref)
- {
- void *ptr = C_PTR(pointer)->pointer;
- int true_offset = fixnum_value(offset);
-
- if (deref == obj_False)
- /* Don't dereference -- just increment */
- return convert_c_object(cls, (void *)((int)ptr + true_offset), FALSE);
- else if (cls == obj_CharacterClass || cls == obj_BooleanClass)
- /* byte size object -- dereference as (char *) */
- return convert_c_object(cls, (void *)*((char *)ptr + true_offset),
- FALSE);
- else
- /* pointer size ofject -- dereference as (void **) */
- return convert_c_object(cls, *(void **)((char *)ptr + true_offset),
- FALSE);
- }
-
- /* Sets the value of a "slot" in the "structure" pointed to by a */
- /* <c-pointer>. */
- obj_t c_pointer_field_setter(obj_t value, obj_t /* <c-pointer> */ pointer,
- obj_t /* <integer> */ offset)
- {
- obj_t cls = object_class(value);
- void *ptr = C_PTR(pointer)->pointer;
- int true_offset = fixnum_value(offset);
-
- if (cls == obj_CharacterClass || cls == obj_BooleanClass)
- /* byte size object -- dereference as (char *) */
- *((char *)ptr + true_offset) = ((char) get_c_object(value));
- else
- /* pointer size ofject -- dereference as (void **) */
- *((void **)((char *)ptr + true_offset)) = get_c_object(value);
- return value;
- }
-
- obj_t c_pointer_as(obj_t /* <class> */ cls,
- obj_t /* <statically-typed-pointer> */ object)
- {
- if (instancep(object, cls))
- return object;
- else
- return make_c_pointer(cls, C_PTR(object)->pointer);
- }
-
- obj_t c_ptr_as_int(obj_t /* <class> */ cls,
- obj_t /* <statically-typed-pointer> */ object)
- {
- return make_fixnum((int) C_PTR(object)->pointer);
- }
-
- obj_t c_int_as_ptr(obj_t /* <class> */ cls,
- obj_t /* <integer> */ object)
- {
- if (instancep(object, cls))
- return object;
- else
- return make_c_pointer(cls, (void *)fixnum_value(object));
- }
-
- obj_t c_pointer_equal(obj_t left, obj_t right)
- {
- if (C_PTR(left)->pointer == C_PTR(right)->pointer)
- return obj_True;
- else
- return obj_False;
- }
-
- /* GC routines. */
-
- int scav_c_pointer(struct object *obj)
- {
- return sizeof(struct c_pointer);
- }
-
- obj_t trans_c_pointer(obj_t cptr)
- {
- return transport(cptr, sizeof(struct c_pointer));
- }
-
- static int scav_foreign_file(struct object *obj)
- {
- scavenge(&((struct foreign_file *)obj)->file_name);
- return sizeof(struct foreign_file)
- + ((struct foreign_file *)obj)->extra_size;
- }
-
- static obj_t trans_foreign_file(obj_t cptr)
- {
- return transport(cptr, sizeof(struct foreign_file)
- + FOREIGN_FILE(cptr)->extra_size);
- }
-
- void scavenge_c_roots(void)
- {
- scavenge(&obj_CPointerClass);
- scavenge(&obj_ForeignFileClass);
- scavenge(&obj_NullPointer);
- if (mindy_dynamic_syms != NULL)
- /* Let it be scavenged and we'll recreate it at need */
- mindy_dynamic_syms = NULL;
- scavenge(&mindy_explicit_syms);
- }
-
-
- /* Init stuff. */
-
- void make_c_classes(void)
- {
- obj_CPointerClass
- = make_builtin_class(scav_c_pointer, trans_c_pointer);
- CLASS(obj_CPointerClass)->class = obj_StaticTypeClass;
- CLASS(obj_CPointerClass)->sealed_p = FALSE;
- obj_ForeignFileClass
- = make_builtin_class(scav_foreign_file, trans_foreign_file);
- }
-
- void init_c_classes(void)
- {
- init_builtin_class(obj_CPointerClass, "<statically-typed-pointer>",
- obj_ObjectClass, NULL);
- def_printer(obj_CPointerClass, print_c_pointer);
- init_builtin_class(obj_ForeignFileClass, "<foreign-file>", obj_ObjectClass,
- NULL);
- def_printer(obj_ForeignFileClass, print_foreign_file);
- }
-
- void init_c_functions(void)
- {
- extern void build_explicit_syms(void);
-
- /* This is required by find_c_function and find_c_pointer */
- build_explicit_syms();
-
- define_method("find-c-function",
- list1(obj_ByteStringClass), FALSE,
- list1(pair(symbol("file"), obj_Unbound)),
- FALSE, obj_ObjectClass, find_c_function);
- define_method("find-c-pointer",
- list1(obj_ByteStringClass), FALSE,
- list1(pair(symbol("file"), obj_Unbound)),
- FALSE, obj_ObjectClass, find_c_ptr);
- define_method("load-object-file",
- list1(obj_ListClass), FALSE,
- list1(pair(symbol("include"), obj_Nil)), FALSE,
- obj_ObjectClass, load_c_file);
- define_method("signed-byte-at", list1(obj_CPointerClass), FALSE,
- list1(pair(symbol("offset"), make_fixnum(0))), FALSE,
- obj_IntegerClass, signed_byte_at);
- define_method("signed-byte-at-setter",
- list2(obj_IntegerClass, obj_CPointerClass), FALSE,
- list1(pair(symbol("offset"), make_fixnum(0))), FALSE,
- obj_IntegerClass, signed_byte_at_setter);
- define_method("unsigned-byte-at", list1(obj_CPointerClass), FALSE,
- list1(pair(symbol("offset"), make_fixnum(0))), FALSE,
- obj_IntegerClass, unsigned_byte_at);
- define_method("unsigned-byte-at-setter",
- list2(obj_IntegerClass, obj_CPointerClass), FALSE,
- list1(pair(symbol("offset"), make_fixnum(0))), FALSE,
- obj_IntegerClass, unsigned_byte_at_setter);
- define_method("signed-short-at", list1(obj_CPointerClass), FALSE,
- list1(pair(symbol("offset"), make_fixnum(0))), FALSE,
- obj_IntegerClass, signed_short_at);
- define_method("signed-short-at-setter",
- list2(obj_IntegerClass, obj_CPointerClass), FALSE,
- list1(pair(symbol("offset"), make_fixnum(0))), FALSE,
- obj_IntegerClass, signed_short_at_setter);
- define_method("unsigned-short-at", list1(obj_CPointerClass), FALSE,
- list1(pair(symbol("offset"), make_fixnum(0))), FALSE,
- obj_IntegerClass, unsigned_short_at);
- define_method("unsigned-short-at-setter",
- list2(obj_IntegerClass, obj_CPointerClass), FALSE,
- list1(pair(symbol("offset"), make_fixnum(0))), FALSE,
- obj_IntegerClass, unsigned_short_at_setter);
- define_method("signed-long-at", list1(obj_CPointerClass), FALSE,
- list1(pair(symbol("offset"), make_fixnum(0))), FALSE,
- obj_IntegerClass, signed_long_at);
- define_method("signed-long-at-setter",
- list2(obj_IntegerClass, obj_CPointerClass), FALSE,
- list1(pair(symbol("offset"), make_fixnum(0))), FALSE,
- obj_IntegerClass, signed_long_at_setter);
- define_method("unsigned-long-at", list1(obj_CPointerClass), FALSE,
- list1(pair(symbol("offset"), make_fixnum(0))), FALSE,
- obj_IntegerClass, unsigned_long_at);
- define_method("unsigned-long-at-setter",
- list2(obj_IntegerClass, obj_CPointerClass), FALSE,
- list1(pair(symbol("offset"), make_fixnum(0))), FALSE,
- obj_IntegerClass, unsigned_long_at_setter);
- define_method("pointer-at", list1(obj_CPointerClass), FALSE,
- list2(pair(symbol("offset"), make_fixnum(0)),
- pair(symbol("class"), obj_CPointerClass)), FALSE,
- obj_IntegerClass, pointer_at);
- define_method("pointer-at-setter",
- list2(obj_CPointerClass, obj_CPointerClass), FALSE,
- list1(pair(symbol("offset"), make_fixnum(0))), FALSE,
- obj_IntegerClass, pointer_at_setter);
- define_method("+", list2(obj_CPointerClass, obj_IntegerClass), FALSE,
- obj_False, FALSE, obj_CPointerClass, pointer_add);
- define_method("-", list2(obj_CPointerClass, obj_CPointerClass), FALSE,
- obj_False, FALSE, obj_IntegerClass, pointer_subtract);
- define_method("c-pointer-slot",
- listn(4, obj_CPointerClass, obj_IntegerClass,
- obj_TypeClass, obj_ObjectClass),
- FALSE, obj_False, FALSE,
- obj_ObjectClass, c_pointer_field);
- define_method("c-pointer-slot-setter",
- list3(obj_ObjectClass, obj_CPointerClass, obj_IntegerClass),
- FALSE, obj_False, FALSE,
- obj_ObjectClass, c_pointer_field_setter);
- define_method("as",
- list2(obj_StaticTypeClass, obj_CPointerClass), FALSE,
- obj_False, FALSE,
- obj_ObjectClass, c_pointer_as);
- define_method("as",
- list2(obj_IntegerClass, obj_CPointerClass), FALSE,
- obj_False, FALSE,
- obj_ObjectClass, c_ptr_as_int);
- define_method("as",
- list2(obj_StaticTypeClass, obj_IntegerClass), FALSE,
- obj_False, FALSE,
- obj_ObjectClass, c_int_as_ptr);
- define_method("=", list2(obj_CPointerClass, obj_CPointerClass),
- FALSE, obj_False, FALSE,
- obj_BooleanClass, c_pointer_equal);
- obj_NullPointer = make_c_pointer(obj_CPointerClass, 0);
- define_constant("null-pointer", obj_NullPointer);
- }
-